🎖️GitЯра🎖️
Commit 212bc596e37fd45e75b830e36cd825972f12cf79
Parents : 9fa9f1e
Author : James Rich <2199651+jamesarich@users.noreply.github.com>
Signature : Signature validation error
Date : 2026-08-12T19:13:59Z
Committer : GitHub <noreply@github.com>
Date : 2026-08-12T19:13:59Z
fix(ble): enable Kable preConflate to prevent scan-callback ANRs (#6652)
Changes
5 files changed, 22 insertions(+), 0 deletions(-)
Diff
diff --git a/core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt b/core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
index 5085a8f5b5..5deccbe785 100644
--- a/core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
+++ b/core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
@@ -21,9 +21,16 @@ import com.juul.kable.AndroidPeripheral
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
import com.juul.kable.PooledThreadingStrategy
+import com.juul.kable.ScannerBuilder
import com.juul.kable.toIdentifier
import org.meshtastic.core.model.util.anonymize
+// Kable's default trySendBlocking can park the scan-callback (sometimes main) thread in dense BLE
+// environments, causing ANRs; preConflate drops excess advertisements instead (kable#654).
+internal actual fun ScannerBuilder.platformScanConfig() {
+ preConflate = true
+}
+
/** Android's scanner filters on address in hardware, so Kable's `Filter.Address` works natively here. */
internal actual val supportsNativeAddressScanFilter: Boolean = true
diff --git a/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleScanner.kt b/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleScanner.kt
index 56191b671f..a53680775a 100644
--- a/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleScanner.kt
+++ b/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleScanner.kt
@@ -75,6 +75,7 @@ open class KableBleScanner(private val loggingConfig: BleLoggingConfig) : BleSca
internal open fun advertisements(filter: KableScanFilter): Flow<KableScanResult> {
val scanner = Scanner {
+ platformScanConfig()
logging { applyConfig(loggingConfig) }
when (filter) {
KableScanFilter.None -> Unit
diff --git a/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt b/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
index 171f6286bf..8a1e3bd1a2 100644
--- a/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
+++ b/core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
@@ -18,6 +18,10 @@ package org.meshtastic.core.ble
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
+import com.juul.kable.ScannerBuilder
+
+/** Platform-specific configuration for the Scanner builder (e.g. Android's `preConflate`). */
+internal expect fun ScannerBuilder.platformScanConfig()
/**
* Whether Kable honours a scan filter on device address here. Android only: `Filter.Address` throws on Apple/JS, and
diff --git a/core/ble/src/iosMain/kotlin/org/meshtastic/core/ble/NoopStubs.kt b/core/ble/src/iosMain/kotlin/org/meshtastic/core/ble/NoopStubs.kt
index 6e9baf4d11..d6bc236b02 100644
--- a/core/ble/src/iosMain/kotlin/org/meshtastic/core/ble/NoopStubs.kt
+++ b/core/ble/src/iosMain/kotlin/org/meshtastic/core/ble/NoopStubs.kt
@@ -18,10 +18,15 @@ package org.meshtastic.core.ble
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
+import com.juul.kable.ScannerBuilder
// Kable's `Filter.Address` throws UnsupportedOperationException on Apple.
internal actual val supportsNativeAddressScanFilter: Boolean = false
+internal actual fun ScannerBuilder.platformScanConfig() {
+ // No-op: preConflate is Android-only.
+}
+
/** No-op stubs for iOS target in core:ble. */
internal actual fun PeripheralBuilder.platformConfig(device: BleDevice, autoConnect: () -> Boolean) {
// No-op for stubs
diff --git a/core/ble/src/jvmMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt b/core/ble/src/jvmMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
index 0b4b4ae85f..188a1ad33b 100644
--- a/core/ble/src/jvmMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
+++ b/core/ble/src/jvmMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt
@@ -18,8 +18,13 @@ package org.meshtastic.core.ble
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
+import com.juul.kable.ScannerBuilder
import com.juul.kable.toIdentifier
+internal actual fun ScannerBuilder.platformScanConfig() {
+ // No-op: preConflate is Android-only.
+}
+
// Kable's btleplug backend evaluates scan filters with a hardcoded `address = null`, so an address filter matches
// nothing and the scan yields no advertisements at all.
internal actual val supportsNativeAddressScanFilter: Boolean = false
Served by rngit 1.4.2 - Generated in 0.13s